import Docxtemplater from "docxtemplater";
import PizZip from "pizzip";
import PizZipUtils from "pizzip/utils/index.js";
import ImageModule from 'docxtemplater-image-module-free';
import { saveAs } from "file-saver";
import { ElMessage } from 'element-plus';

class ExportWord {
    constructor(option) {
        try {
            if (!option.url) {
                throw new Error('模板文件路径不能为空');
            }
            this.url = option.url;
            this.fileName = option.filename || 'document.docx';
            this.data = option.obj || {};
            this.docContent = null;

            validateTemplateData(this.data);
        } catch (error) {
            ElMessage.error(error.message);
            throw error;
        }
    }

    initWord(_callback) {
        this.loadFile(this.url, (error, _content) => {
            if (error) {
                console.error('加载模板文件失败:', error);
                ElMessage.error('模板文件加载失败，请检查文件路径');
                return;
            }

            this.setPizZip(error, _content)
                .then(res => {
                    _callback(this);
                })
                .catch(err => {
                    console.error('处理文件失败:', err);
                    ElMessage.error('文件处理失败，请重试');
                });
        });
    }

    loadFile(url, callback) {
        try {
            const fullUrl = url.startsWith('http') ? url : window.location.origin + url;
            PizZipUtils.getBinaryContent(fullUrl, callback);
        } catch (error) {
            console.error('读取文件失败:', error);
            callback(new Error('读取文件失败'), null);
        }
    }

    setPizZip(error, _content) {
        const imageOpts = {
            getImage: function (tagValue, tagName) {
                return new Promise(function (resolve, reject) {
                    PizZipUtils.getBinaryContent(tagValue, function (error, content) {
                        if (error) {
                            return reject(error);
                        }
                        return resolve(content);
                    });
                });
            },
            getSize: (img, tagValue, tagName) => {
                return new Promise(function (resolve, reject) {
                    const image = new Image();
                    image.src = tagValue;
                    image.onload = function () {
                        resolve([image.width, image.height]);
                    };
                    image.onerror = function (e) {
                        console.error("Image load error:", tagValue);
                        reject(e);
                    };
                });
            }
        };

        try {
            const zip = new PizZip(_content);
            this.docContent = new Docxtemplater(zip, {
                modules: [new ImageModule(imageOpts)],
                paragraphLoop: true,
                linebreaks: true
            });

            return this.setTemplateContent(this.data);
        } catch (error) {
            console.error('初始化文档失败:', error);
            throw error;
        }
    }

    setTemplateContent(_obj) {
        try {
            return this.docContent.renderAsync(_obj);
        } catch (error) {
            this.handleTemplateError(error);
            throw error;
        }
    }

    handleTemplateError(error) {
        if (error.properties && error.properties.errors instanceof Array) {
            const errorMessages = error.properties.errors
                .map(error => error.properties.explanation)
                .join("\n");
            console.error("模板错误:", errorMessages);
            ElMessage.error('模板渲染失败，请检查模板格式');
        }
    }

    downloadFile() {
        try {
            const out = this.docContent.getZip().generate({
                type: "blob",
                mimeType: "application/vnd.openxmlformats-officedocument.wordprocessingml.document"
            });
            saveAs(out, this.fileName);
        } catch (error) {
            console.error('生成文件失败:', error);
            ElMessage.error('生成文件失败，请重试');
            throw error;
        }
    }
}
const validateTemplateData = (data) => {
    const required = ['name'];
    const missing = required.filter(field => !data[field]);

    if (missing.length > 0) {
        throw new Error(`缺少必要字段: ${missing.join(', ')}`);
    }

    return true;
};

const checkTemplatePath = async (url) => {
    try {
        const response = await fetch(url);
        if (!response.ok) {
            throw new Error('模板文件不存在');
        }
        return true;
    } catch (error) {
        console.error('检查模板文件失败:', error);
        return false;
    }
};

export default ExportWord;